extends Node2D
signal on_start()
signal on_end()
signal on_update_experience(value : int)
signal send_level_pass_event()
signal send_turn_pass_event()
signal send_turn_end_event()

@onready var line_2d: Line2D = $Line2D
@onready var base_grid: BaseGrid = $BaseGrid
@onready var build_group: Marker2D = $BuildGroup
@onready var enemy_group: Marker2D = $EnemyGroup
@onready var enemy_maker_timer: Timer = $EnemyMakerTimer
@onready var check_pass_timer: Timer = $CheckPassTimer
@onready var enemy_ready_pos: Marker2D = $EnemyReadyPos
@onready var candidate: CanvasLayer = $Candidate
@onready var candidate_bg: Panel = $CandidateBg
@onready var buff: CanvasLayer = $Buff
@onready var game: CanvasLayer = $Game

const BASE_GRID = preload("uid://cvedqvltcqghn")
const BASE_BUILD = preload("uid://drpy76vualpwo")
const BASE_ENEMY = preload("uid://covtehykugayj")
const BASE_WEAPON = preload("uid://b8k8f0xu5w811")

var current_level : int
var current_turn : int
var enemy_list : Array
#var build_list : Dictionary
var base_build : BaseBuild
var base_weapon : Weapon
var v_2 : Node2D
var experience : int
var current_experience_level : int

func _ready() -> void:
	GlobalVariable.main = self
	_init_signal()
	_init_base_weapon()
	_init_base_build()
	_init_enemy()
	_init_enemy_maker_timer()
	_init_check_pass_timer()
	_init_candidate_v2()
	_init_candidate_build()
	_init_game_ui()
	_init_test_ready()

func _init_signal() -> void :
	GlobalVariable.enemy_group = enemy_group

func _init_base_weapon() -> void :
	base_weapon = BASE_WEAPON.instantiate()
	GlobalVariable.base_weapon = base_weapon
	call_deferred("add_child",base_weapon)

# 建造基地
func _init_base_build() -> void :
	base_build = BASE_BUILD.instantiate()
	base_build._init_pos(Vector2.ZERO,Vector2i(0,0))
	base_build.set_solid.connect(_on_set_solid)
	base_build.current_xy = base_grid._get_cell_xy(base_build.global_position)
	base_grid._set_block(base_build.global_position,base_build.build_item.block_list)
	base_build.projectile.connect(base_weapon._attack)
	build_group.call_deferred("add_child",base_build)

func _init_build() -> void :
	pass

func _init_enemy() -> void :
	enemy_list.clear()
	var level_data = LevelData.level_data.get(current_level)
	for count in level_data.base_enemy :
		var turn_array = []
		for enemy_index in count :
			var enemy = BASE_ENEMY.instantiate()
			enemy.name = str(enemy_index)
			enemy.global_position = enemy_ready_pos.global_position
			turn_array.append(enemy)
		enemy_list.append(turn_array)

func _init_check_pass_timer() -> void :
	check_pass_timer.timeout.connect(
		func() :
			var size = enemy_group.get_children().size()
			if size == 0 :
				enemy_maker_timer.stop()
				check_pass_timer.stop()
				base_build.attack_interval_timer.stop()
				current_turn += 1
				if LevelData.level_data.get(current_level).base_enemy.size() == current_turn :
					current_level += 1
					current_turn = 0
					send_turn_pass_event.emit()
				if LevelData.level_data.size() == current_level :
					current_turn = 0
					send_level_pass_event.emit()
					return
				send_turn_end_event.emit()
				v_2.call_deferred("_init_card")
				base_grid.on_visible_ban_cell.emit(true)
				candidate_bg.show()
				candidate.show()
				call_deferred("_init_enemy")
	)

func _init_enemy_maker_timer() -> void :
	await get_tree().create_timer(2).timeout
	enemy_maker_timer.timeout.connect(_create_enemy)

func _init_candidate_build() -> void :
	v_2.check_mouse_position_able_build = _check_mouse_position_able_build
	v_2.reset_mouse_position_able_build_cell = _reset_mouse_position_able_build_cell
	v_2.set_solid.connect(_on_set_solid)
	candidate.on_play.connect(_start)
	v_2.position.y += 630.0

func _init_candidate_v2() -> void :
	v_2 = GlobalInstance.V_2.instantiate()
	add_child(v_2)

func _init_game_ui() -> void :
	var level_data = LevelData.level_data.get(current_level)
	var level_experience = level_data.level_experience
	game._init_ui(level_experience.get(current_experience_level))
	on_update_experience.connect(game._set_experience)

# 开始游戏
func _start() -> void :
	v_2._start()
	candidate.hide()
	candidate_bg.hide()
	base_build._start_attack()
	enemy_maker_timer.start()
	on_start.emit()
	base_grid.on_visible_ban_cell.emit(false)
	await get_tree().create_timer(1).timeout
	check_pass_timer.start()

func _end() -> void :
	base_build._stop_attack()
	enemy_maker_timer.stop()
	on_end.emit()

func _paused() -> void :
	get_tree().set_pause(true)

# 创建敌人
func _create_enemy() -> void :
	var xy = base_grid._get_random_maker_xy()
	var pos = base_grid._get_pos(xy)
	# TODO
	#var path : Array = GlobalVariable.astar_grid.get_point_path(xy, Vector2i(0,0),true)
	#var frist_point = path.pop_front()
	var turn = enemy_list.get(current_turn)
	var enemy = turn.pop_back()
	if not enemy : return
	enemy._set_attack([],pos)
	enemy.reset_enemy_path.connect(_on_reset_enemy_path)
	enemy.tree_exited.connect(_on_experience.bind(enemy))
	enemy_group.call_deferred("add_child",enemy)
	#if not enemy_list :
		#enemy_maker_timer.stop()

func _on_set_solid(xy : Vector2) -> void :
	base_grid.call_deferred("_remove_block",xy)

func _on_reset_enemy_path(enemy : BaseEnemy) -> void :
	var attack_target = null
	for build in build_group.get_children() :
		if attack_target :
			var l1 = (enemy.global_position - attack_target.global_position).length()
			var l2 = (enemy.global_position - build.global_position).length()
			attack_target = attack_target if l1 < l2 else build
		else :
			attack_target = build
	if not attack_target : return
	
	var enemy_pos = enemy.global_position
	var xy = base_grid._get_cell_xy(enemy_pos)
	var target_xy = base_grid._get_cell_xy(attack_target.global_position)
	var path : Array = GlobalVariable.astar_grid.get_point_path(xy, target_xy,true)
	if not path : return
	path.pop_front()
	enemy._set_attack(path)

func _check_mouse_position_able_build(build : BaseBuild) -> bool :
	var mouse_pos = build.global_position
	var cell = base_grid._get_cell(mouse_pos)
	if not cell : return false
	if cell._check_disable_build() : return false
	if base_grid._check_disable_build(cell.xy) : return false
	build.reparent(build_group)
	if build.current_xy : _on_set_solid(build.current_xy)
	build._init_pos(cell.global_position,cell.xy)
	base_grid._set_block(build.global_position,build.build_item.block_list)
	return true

#func _check_mouse_position_able_merge(_current : TextureRect) -> bool :
	#var mouse_pos = get_global_mouse_position()
	#var cell = base_grid._get_cell(mouse_pos)
	#if not cell : return false
	#if cell._check_disable_build() : return false
	#if base_grid._check_disable_build(cell.xy) :
		#var a_build = build_list.get(cell.xy)
		#if a_build :
			#if a_build.build_item.build_name == "BaseBuild" : return false
			#if a_build.build_item.current_level>a_build.build_item.build_level.size()-1:
				#a_build.model.self_modulate = Color.FIREBRICK
				#return false
			#return true
		#return false
	#return true

func _reset_mouse_position_able_build_cell(build : Area2D, is_check : bool = false) -> bool :
	var mouse_pos = build.global_position
	var cb = candidate_bg.get_rect()
	if cb.has_point(mouse_pos) and build.is_in_group("blank_block") :
		return false
	return base_grid._reset_able_build_cell(mouse_pos,is_check,build)

func _on_experience(enemy : Node2D) -> void :
	var enemy_item = enemy.enemy_item
	experience += enemy_item.score
	var level_data = LevelData.level_data.get(current_level)
	var level_experience = level_data.level_experience
	if current_experience_level >= level_experience.size() : return
	if experience > level_experience.get(current_experience_level) :
		buff.call_deferred("_show")
		game._init_ui(level_experience.get(current_experience_level))
		current_experience_level += 1
	var score = level_experience.get(current_experience_level-1) if current_experience_level>0 else 0
	on_update_experience.emit(experience-score)

#########################################TEST####################################
var child_dic : Dictionary = {
	"RELAY_DEVICE" : preload("res://build/block/relay_device.tscn")
}

#var test_build

func _init_test_ready() -> void :
	#test_build = RELAY_DEVICE.duplicate(true).instantiate()
	#build_group.add_child(test_build)
	pass

#func _unhandled_input(event: InputEvent) -> void:
	#if event as InputEventMouseButton :
		#
		#if event.is_pressed() :
			#var cell = base_grid._get_cell(get_global_mouse_position())
			#if not cell : return
			#if base_grid._check_disable_build(cell.xy) :
				#print("不能建造！")
				#return
			#var build = RELAY_DEVICE.duplicate(true).instantiate()
			#build.build_item.attack_interval = randf_range(1,2)
			#build._init_pos(cell.global_position,cell.xy)
			#build.projectile.connect(base_weapon._attack)
			#base_grid._set_block(build.global_position,build.build_item.block_list)
			#build_group.add_child(build)
			

#func _process(_delta: float) -> void:
	#if test_build :
		#test_build.global_position = get_global_mouse_position()
